package cn.elead.chaos.sso.server.web.monitor.controller;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.elead.chaos.core.enums.BusinessType;
import cn.elead.chaos.framework.monitor.operlog.Log;
import cn.elead.chaos.framework.web.global.ApiAssert;
import cn.elead.chaos.framework.web.global.ErrorCodeEnum;
import cn.elead.chaos.framework.web.global.response.UnifiedReturn;
import cn.elead.chaos.mybatils.web.controller.BaseController;
import cn.elead.chaos.mybatils.web.page.TableDataInfo;
import cn.elead.chaos.sso.core.user.LoginUser;
import cn.elead.chaos.sso.core.util.SsoUtils;
import cn.elead.chaos.sso.server.web.login.service.RedisSaveService;
import cn.elead.chaos.sso.server.web.login.service.StringRedisService;
import cn.elead.chaos.sso.server.web.monitor.domain.SysLogininfor;
import cn.elead.chaos.sso.server.web.monitor.service.ISysLogininforService;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

/**
 * 在线用户监控
 * 
 * @author luopeng
 */
@Controller
@RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController {
	private String prefix = "monitor/online";

	@Autowired
	private StringRedisService<String, LoginUser> userRedisService;
	
	@Autowired
	private RedisSaveService redisSaveService;

	@Autowired
	private ISysLogininforService logininforService;

	@GetMapping
	@RequiresPermissions("monitor:online:view")
	public String online() {
		return prefix + "/online";
	}

	@ResponseBody
	@UnifiedReturn
	@PostMapping("/list")
	@RequiresPermissions("monitor:online:list")
	public TableDataInfo<SysLogininfor> list(SysLogininfor userOnline) {
		Set<String> sessions = userRedisService.keys(RedisSaveService.CACHE_USER + "*");
		if (ObjectUtil.isNotNull(sessions)) {
			sessions = sessions.stream().map(a -> StrUtil.replace(a, RedisSaveService.CACHE_USER, StrUtil.EMPTY)).collect(Collectors.toSet());
		}
		userOnline.setSessions(sessions);
		
		List<SysLogininfor> list = logininforService.selectLogininBySessions(userOnline);
		return getDataTable(list);
	}

	@ResponseBody
	@PostMapping("/batchForceLogout")
	@RequiresPermissions("monitor:online:batchForceLogout")
	@Log(title = "在线用户", businessType = BusinessType.FORCE)
	public String batchForceLogout(@RequestParam("ids[]") String[] ids) {
		for (String sessionId : ids) {
			LoginUser loginUser = redisSaveService.getLoginUser(sessionId);
			ApiAssert.notNull(ErrorCodeEnum.BAD_REQUEST.convert("用户已下线"), loginUser);
			ApiAssert.notEquals(ErrorCodeEnum.BAD_REQUEST.convert("当前登陆用户无法强退"), sessionId, SsoUtils.getToken());
			redisSaveService.deleteLoginUserFromRedis(sessionId);
		}

		return null;
	}

	@ResponseBody
	@PostMapping("/forceLogout")
	@RequiresPermissions("monitor:online:forceLogout")
	@Log(title = "在线用户", businessType = BusinessType.FORCE)
	public String forceLogout(String sessionId) {
		LoginUser loginUser = redisSaveService.getLoginUser(sessionId);
		ApiAssert.notNull(ErrorCodeEnum.BAD_REQUEST.convert("用户已下线"), loginUser);
		ApiAssert.notEquals(ErrorCodeEnum.BAD_REQUEST.convert("当前登陆用户无法强退"), sessionId, SsoUtils.getToken());
		redisSaveService.deleteLoginUserFromRedis(sessionId);
		return null;
	}
}
